home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume90
/
examples
/
spiders
/
part01
/
spiders.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-17
|
12KB
|
379 lines
/************************************************************************/
/* */
/* ###################### */
/* A n t h o n y ## ## ## */
/* ########## */
/* T h y s s e n #### ## #### */
/* #### ## #### */
/* #### ## #### */
/* */
/************************************************************************/
/*
** Spiders - for AMIGA under lattace C
*/
#include <stdio.h>
#include <string.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <exec/exec.h>
#include <proto/all.h>
#define BM_SRC 0xC0 /* minterm source only */
#define BM_DST 0xA0 /* minterm destination only */
#include "spiders.h"
struct Library *IntuitionBase = NULL, *GfxBase = NULL;
struct Remember *Remember = NULL;
struct Screen *WBScrn = NULL;
struct Window *Window = NULL; /* Window pointer */
struct Task *MyTask = NULL; /* my tasks address */
struct IntuiMessage *message;
ULONG WindowSignal; /* IDCMP window signal */
int WBDepth, WBScrX, WBScrY; /* Screen info */
struct NewWindow NW = {
30, 200, 205, 10, 0, 1, /* position, size and colors */
CLOSEWINDOW, /* IDCMP messages */
ACTIVATE| SIMPLE_REFRESH| WINDOWDEPTH|
WINDOWDRAG| WINDOWCLOSE, /* window flags */
NULL, NULL, /* gadget, checkmark */
(UBYTE *) " -- Spiders -- ", /* name of window */
NULL,NULL, /* screen-> , BitMap-> */
0,0,0,0, /* min and max size (disable) */
WBENCHSCREEN /* screen type */
};
typedef struct {
int x, y;
} point;
typedef enum {
Sleeping, /* Waiting to start - off screen */
Waiting, /* Comtemplating the decent */
Decending, /* Going down screen */
Landed, /* Getting a bit of screen */
Ascending, /* Going up the screen */
Munching /* eating its bit of screen */
} status;
static struct {
point ulc; /* upper left corner of spider */
status stat; /* current status of crab */
int time; /* time count down to actions */
struct RastPort bitRP; /* raster port for screen bit */
struct BitMap bitBM; /* bit map for the screen bit */
} Spider[NUMBER]; /* spider' state */
/* images and masks */
unsigned short chip SpiderImage[] =
# include "spiderimage.i"
unsigned short chip MaskImage[] =
# include "maskimage.i"
struct RastPort SpiderRP, MaskRP, ScreenRP; /* RastPorts */
struct BitMap SpiderBM, MaskBM; /* BitMaps */
#ifdef CBACK
/* Cback.o varibles */
long _stack = 2000;
char *_procname = "spiders";
long _priority = -1;
long _BackGroundIO = 0;
#endif
/* function declarations */
extern void Init(), OpenLibraries(), SpiderExit(), Cycle();
extern void HideScrBit(), DrawScrBit(), HideSpider(), DrawSpider();
extern int TestDown(), RandInt();
extern void RandInit();
void
_main()
/* I am not using printf's functions so _main() will do */
{
Init(); /* set up initial grey crab layer */
for (;;) { /* no way out! */
Cycle(); /* move the crabs */
}
/* NOTREACHED */
}
void
Init()
{
int i, j;
RandInit();
OpenLibraries(); /* open the various system structures */
if( !(Window = OpenWindow( &NW )) )
SpiderExit();
WindowSignal = 1<<Window->UserPort->mp_SigBit;
MyTask = FindTask( NULL );
WBScrn = Window->WScreen;
WBDepth = 2; /* Assume it (for WB pic progs) */
WBScrX = WBScrn->Width -XSPIDER;
WBScrY = WBScrn->Height -YSPIDER;
/* grab a copy of the screens raster port */
memcpy( (char *)&ScreenRP, (char *)&WBScrn->RastPort,
sizeof( struct RastPort ) );
/* define spiders */
for (i = 0; i < NUMBER; i++) {
Spider[i].stat = Sleeping; /* spider is just sleeping */
Spider[i].time = RandInt(1, SLEEPTIME);
/* initialise bitmaps */
InitRastPort( &Spider[i].bitRP );
Spider[i].bitRP.BitMap = &Spider[i].bitBM;
InitBitMap( &Spider[i].bitBM, WBDepth, XMASK, YMASK);
for( j = 0; j < WBDepth; j++ )
if( !( Spider[i].bitBM.Planes[j] = (PLANEPTR)
AllocRemember( &Remember, RASSIZE(XMASK, YMASK),
MEMF_CHIP | MEMF_CLEAR ) ) )
SpiderExit();
}
InitRastPort( &MaskRP );
MaskRP.BitMap = &MaskBM;
InitBitMap( &MaskBM, WBDepth, XMASK, YMASK);
for( j = 0; j < WBDepth; j++ )
MaskBM.Planes[j] = (PLANEPTR) &MaskImage;
InitRastPort( &SpiderRP );
SpiderRP.BitMap = &SpiderBM;
InitBitMap( &SpiderBM, 1, XSPIDER, YSPIDER);
SpiderBM.Planes[0] = (PLANEPTR) &SpiderImage;
}
void
OpenLibraries()
{
if( ! (IntuitionBase = OpenLibrary( "intuition.library", 0 )) )
SpiderExit();
if( ! (GfxBase = OpenLibrary( "graphics.library", 0 )) )
SpiderExit();
}
void
SpiderExit()
/* exit - remove all traces */
{
FreeRemember( &Remember, TRUE ); /* free all allocated memory */
if( Window ) CloseWindow( Window );
if( GfxBase ) CloseLibrary( GfxBase );
if( IntuitionBase ) CloseLibrary( IntuitionBase );
exit(0);
}
void
Cycle()
/* one motion cycle for all spiders */
{
int s; /* spider to do */
/* test for window closure */
if( message = (void *)GetMsg(Window->UserPort) ) {
ReplyMsg( (void *) message );
switch( message->Class ) {
case CLOSEWINDOW : /* window closed message */
SpiderExit();
}
} /* Message test */
#if DELAY
Delay(DELAY);
#endif
for (s = 0; s < NUMBER; s++) {
switch( Spider[s].stat ) {
case Sleeping:
{
int i, test;
if( --Spider[s].time ) break; /* spider not yet ready to start */
do {
Spider[s].ulc.x = RandInt(0, WBScrX);
test = TRUE; /* assume this position is OK */
for(i = 0; i < NUMBER; i++)
if( Spider[i].stat != Sleeping &&
Spider[s].ulc.x > Spider[i].ulc.x - XSPIDER &&
Spider[i].ulc.x > Spider[s].ulc.x - XSPIDER ) {
test = FALSE; /* spider on screen already in this position */
break;
}
} while ( !test ); /* repeat search until good position found */
Spider[s].ulc.y = SCREENTOP;
Spider[s].stat = Waiting;
Spider[s].time = WAITTIME;
DrawSpider(s);
}
break;
case Waiting:
if( Spider[s].time-- ) break;
Spider[s].stat = Decending;
break;
case Decending:
{
int y, speed;
y = Spider[s].ulc.y;
speed = TestDown(s); /* check on landing or screen bottom */
y += speed; /* Decend quickly or stop? */
if( !speed )
Spider[s].stat = Landed;
Spider[s].ulc.y = y;
DrawSpider(s); /* don't hide spide to leave ... trail */
}
break;
case Landed:
/* bit of screen already read in testdown() just wait */
Spider[s].stat = Ascending;
break;
case Ascending:
{
int y;
y = Spider[s].ulc.y;
y--; /* Ascend at a slow rate */
if( y < SCREENTOP ) { /* Spider hit rock bottom */
y = SCREENTOP;
Spider[s].stat = Munching;
Spider[s].time = (YMASK+2) * EATRATE-1;
}
HideSpider(s); HideScrBit(s);
Spider[s].ulc.y = y;
DrawSpider(s); DrawScrBit(s);
}
break;
case Munching:
if( !Spider[s].time ) {
/* reinitialize start */
Spider[s].stat = Sleeping;
Spider[s].time = RandInt(1, SLEEPTIME); /* random delay in starting */
HideSpider(s);
break;
}
if( !(Spider[s].time-- % EATRATE ) ) { /* eat another bit? */
HideScrBit(s);
ScrollRaster( &Spider[s].bitRP, 0, 1, 0, 0, XMASK-1, YMASK-1);
DrawScrBit(s);
}
break;
}
} /* move next spider */
}
int
TestDown(s)
int s;
/* returns distance to first screen bit below spider */
/* if the Spider is withing SPEED of that piece */
/* Also gets the actual piece into the bitRP of spider */
{
int i, j, size, speed = SPEED;
UBYTE *bits0, *bits1;
/* clear out any old image */
SetRast( &Spider[s].bitRP, 0 );
size = WBScrY - Spider[s].ulc.y;
if( size > YMASK ) size = YMASK; /* reduce image size */
if( size < speed ) speed = size; /* reduce speed - don't over shoot */
if( !size ) return 0; /* oops rock bottom! */
/* get a image from screen */
ClipBlit( &ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y + YSPIDER,
&Spider[s].bitRP, 0, 0,
XMASK, size, BM_SRC);
/* mask out background */
ClipBlit( &MaskRP, 0, 0,
&Spider[s].bitRP, 0, 0,
XMASK, YMASK, BM_SRC & BM_DST);
/* check the data to find distance to landing on screen bit */
bits0 = Spider[s].bitBM.Planes[0];
bits1 = Spider[s].bitBM.Planes[1];
for (i = 0; i < speed; i++)
for( j = 0; j < Spider[s].bitBM.BytesPerRow; j++ )
if( *(bits0++) || *(bits1++) ) /* if a bit in either plane */
return i; /* return distance to screen bit */
return speed; /* return speed */
}
void
HideScrBit(s)
int s;
/* remove screen bit carried */
{
int size;
size = WBScrY - Spider[s].ulc.y;
if( size > YMASK ) size = YMASK; /* reduce image size */
if( !size ) return; /* noting to erase */
ClipBlit( &MaskRP, 0, 0,
&ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y + YSPIDER,
XMASK, size, ~BM_SRC & BM_DST);
}
void
DrawScrBit(s)
int s;
/* draw screen bit carried */
{
int size;
size = WBScrY - Spider[s].ulc.y;
if( size > YMASK ) size = YMASK; /* reduce image size */
if( !size ) return; /* no room to draw */
ClipBlit( &Spider[s].bitRP, 0, 0,
&ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y + YSPIDER,
XMASK, size, BM_SRC | BM_DST);
}
void
HideSpider(s)
int s;
/* over write current spider */
{
ClipBlit( &SpiderRP, 0, 0,
&ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y,
XSPIDER, YSPIDER, 0);
}
void
DrawSpider(s)
int s;
/* Draw the spider on the screen */
{
ClipBlit( &SpiderRP, 0, 0,
&ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y,
XSPIDER, YSPIDER, BM_SRC);
}
void
RandInit()
{
srand((int)time(NULL));
}
int
RandInt(lo, hi) /* generate random integer in range */
int lo, hi; /* range lo..hi inclusive */
{
return lo + (int)( (unsigned)rand() % (hi - lo +1) );
}